package com.kinsin.kinsinutil

import org.junit.After
import org.junit.Assert.*
import org.junit.Before
import org.junit.Test
import java.io.File

class FileUtilsTest {
    private lateinit var tempDir: File
    
    @Before
    fun setup() {
        // 创建临时测试目录
        tempDir = File(System.getProperty("java.io.tmpdir"), "FileUtilsTest")
        tempDir.mkdirs()
    }

    @After
    fun cleanup() {
        // 清理测试目录
        FileUtils.delete(tempDir.absolutePath)
    }

    @Test
    fun testCreateFile() {
        val filePath = File(tempDir, "newFile.txt").absolutePath
        assertTrue(FileUtils.createFile(filePath))
        assertTrue(File(filePath).exists())
    }

    @Test
    fun testCreateDir() {
        val dirPath = File(tempDir, "newDir").absolutePath
        assertTrue(FileUtils.createDir(dirPath))
        assertTrue(File(dirPath).isDirectory)
    }

    @Test
    fun testDeleteFile() {
        val file = File(tempDir, "toBeDeleted.txt").apply { createNewFile() }
        assertTrue(FileUtils.delete(file.absolutePath))
        assertFalse(file.exists())
    }

    @Test
    fun testDeleteDirectoryRecursively() {
        val dir = File(tempDir, "parentDir").apply { mkdir() }
        File(dir, "childFile.txt").apply { createNewFile() }
        File(dir, "childDir").apply { mkdir() }
        
        assertTrue(FileUtils.delete(dir.absolutePath))
        assertFalse(dir.exists())
    }

    @Test
    fun testWriteAndReadString() {
        val filePath = File(tempDir, "textFile.txt").absolutePath
        val content = "Hello 你好\n第二行"
        
        assertTrue(FileUtils.writeStringToFile(content, filePath))
        assertEquals(content, FileUtils.readFileToString(filePath))
    }

    @Test
    fun testAppendString() {
        val filePath = File(tempDir, "appendTest.txt").absolutePath
        val content1 = "First line\n"
        val content2 = "Second line"
        
        assertTrue(FileUtils.writeStringToFile(content1, filePath))
        assertTrue(FileUtils.writeStringToFile(content2, filePath, append = true))
        assertEquals(content1 + content2, FileUtils.readFileToString(filePath))
    }

    @Test
    fun testCopyFile() {
        val src = File(tempDir, "source.txt").apply { writeText("Copy content") }
        val dest = File(tempDir, "dest.txt")
        
        assertTrue(FileUtils.copy(src.absolutePath, dest.absolutePath))
        assertEquals(src.readText(), dest.readText())
    }

    @Test
    fun testMoveFile() {
        val src = File(tempDir, "original.txt").apply { writeText("Moving content") }
        val dest = File(tempDir, "moved.txt")
        
        assertTrue(FileUtils.move(src.absolutePath, dest.absolutePath))
        assertFalse(src.exists())
        assertEquals("Moving content", dest.readText())
    }

    @Test
    fun testRename() {
        val oldFile = File(tempDir, "oldName.txt").apply { createNewFile() }
        val newPath = File(tempDir, "newName.txt").absolutePath
        
        assertTrue(FileUtils.rename(oldFile.absolutePath, newPath))
        assertTrue(File(newPath).exists())
    }

    @Test
    fun testFileSize() {
        val file = File(tempDir, "sizeTest.txt").apply { writeText("12345") }
        assertEquals(5L, FileUtils.getFileSize(file.absolutePath))
    }

    @Test
    fun testDirectorySize() {
        val dir = File(tempDir, "sizeTestDir").apply { mkdir() }
        File(dir, "file1.txt").apply { writeText("123") }
        File(dir, "file2.txt").apply { writeText("45") }
        
        assertEquals(5L, FileUtils.getDirectorySize(dir.absolutePath))
    }

    @Test
    fun testFileExtension() {
        val filePath = "test/demo/image.jpg"
        assertEquals("jpg", FileUtils.getFileExtension(filePath))
    }

    @Test
    fun testMimeType() {
        val jpgFile = File(tempDir, "test.jpg")
        assertEquals("image/jpeg", FileUtils.getMimeType(jpgFile.absolutePath))
    }

    @Test
    fun testExistsCheck() {
        val existingFile = File(tempDir, "existing.txt").apply { createNewFile() }
        assertTrue(FileUtils.exists(existingFile.absolutePath))
        
        val nonExisting = File(tempDir, "nonExisting.txt")
        assertFalse(FileUtils.exists(nonExisting.absolutePath))
    }

    @Test
    fun testTypeCheck() {
        val file = File(tempDir, "typeCheck.txt").apply { createNewFile() }
        val dir = File(tempDir, "typeCheckDir").apply { mkdir() }
        
        assertTrue(FileUtils.isFile(file.absolutePath))
        assertTrue(FileUtils.isDirectory(dir.absolutePath))
    }

    @Test
    fun testSpecialCharacters() {
        val specialName = "测试_čáñ.txt"
        val file = File(tempDir, specialName)
        assertTrue(FileUtils.createFile(file.absolutePath))
        assertTrue(FileUtils.isFile(file.absolutePath))
    }
}